//
//  SGEatNumber.m
//  EatNumber
//
//  Created by zg.shao on 14/12/20.
//  Copyright (c) 2014年 kuwo.cn. All rights reserved.
//

#import "SGEatNumber.h"

static NSString *kGameCellValue = @"gameCellValue";             // 当前关卡的值信息
static NSString *kGameCellProgress = @"gameCellProgress";       // 游戏进度
static NSString *kGameLevelIndex = @"gameLevelIndex";           // 游戏进行的哪一关
static NSString *kPlayerWinLevelIndex = @"playerWinLevelIndex"; // 通关数，从0开始计算。

@interface SGEatNumber () {
    NSInteger _gameCells[GAME_CELL_MAX]; //
    NSString *_tipString; // 新手提示文字
    
    NSMutableArray *_allGameLevels; // 从plist中读取到内存中，考虑到数据量不是很大，直接一次读取完毕吧。
    NSInteger _fromIndex;
    
    NSInteger _gameLevelIndex;      // 玩家当前玩的哪一关
    GameProgress _gameProgress;     // 当前游戏的状态，新开始-》进行中-》玩家胜利-》玩家失败！
    NSInteger _moveSuccessCount;    // 移动成功次数,别的地方不要随便用。
}

@end

@implementation SGEatNumber

- (id)init {
    self = [super init];
    if (self) {
        [self readGameLevelFromPlist];
        [self restoreGameProgress];
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveGameProgress) name:UIApplicationWillResignActiveNotification object:nil];
    }
    
    return self;
}

+ (instancetype)defaultEatNumber {
    static SGEatNumber *s_EatNumber = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        s_EatNumber = [[self class] new];
    });
    
    return s_EatNumber;
}

- (void)readGameLevelFromPlist {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"level" ofType:@"plist"];
    _allGameLevels = [NSMutableArray arrayWithContentsOfFile:path];
}

- (void)newGameWithLevel:(NSInteger)level {
    for (int i = 0; i < GAME_CELL_MAX; i ++) {
        _gameCells[i] = GameCellValue_Blank;
    }
    
    _tipString = @"";
    
    if (level + 1 > [_allGameLevels count]) {
        NSLog(@"还没有这一关呢!!!");
        return ;
    }
    
    NSDictionary *dict = [_allGameLevels objectAtIndex:level];
    for (NSString *key in [dict allKeys]) {
        if ([key isEqualToString:@"tip"]) {
            _tipString = [NSString stringWithFormat:@"%@", [dict objectForKey:@"tip"]];
        } else {
            NSInteger index = [key integerValue];
            _gameCells[index] = [[dict objectForKey:key] integerValue];
        }
    }
    
    _gameLevelIndex   = level;
    _gameProgress     = GameProgress_New;
    _fromIndex        = 0;
    _moveSuccessCount = 0;
}

- (void)newGameWithNextLevel:(BOOL)nextLevel {
    if (nextLevel) {
        _gameLevelIndex += 1;
    }
    
    [self newGameWithLevel:_gameLevelIndex];
}

- (NSInteger)getCurLevel {
    return _gameLevelIndex;
}

- (void)setFromIndex:(NSInteger)index {
    _fromIndex = index;
}

- (NSInteger)fromIndex {
    return _fromIndex;
}

- (NSInteger *)gameCells {
    return _gameCells;
}

- (BOOL)cellCanMoveToIndex:(NSInteger)index {
    if (index == _fromIndex) {
        return NO;
    }
    NSInteger toCellValue = _gameCells[index];
    NSInteger fromCellValue = _gameCells[_fromIndex];
    
    if (fromCellValue <= 0) {
        return NO;
    }
    
    NSInteger nextCellColIndex = GET_COL_INDEX(index);
    NSInteger nextCellRowIndex = GET_ROW_INDEX(index);
    // 都到游戏的边界了，移动不了了。
    if (nextCellColIndex < 0 || nextCellColIndex >= GAME_COL_MAX || nextCellRowIndex < 0 || nextCellRowIndex >= GAME_ROW_MAX) {
        return NO;
    }
    
    // 如果移动的坐标 X Y的差值超过1，那么不能移动。
    if (abs(nextCellColIndex - GET_COL_INDEX(_fromIndex)) + abs(nextCellRowIndex - GET_ROW_INDEX(_fromIndex)) != 1) {
        return NO;
    }
    
    if (toCellValue == -1 || (fromCellValue - toCellValue) == 1) {
        return YES;
    }
    
    return NO;
}

- (NSString *)tipString {
    return _tipString;
}

- (NSInteger)mergeToIndex:(NSInteger)index {
    if (index == _fromIndex) {
        return _gameCells[index];
    }
    
    NSInteger fromCellValue = _gameCells[_fromIndex];
    NSInteger toCellValue = _gameCells[index];
    if (toCellValue == GameCellValue_Blank && fromCellValue == GameCellValue_1) {
        return 0;
    } else if (toCellValue == GameCellValue_0 || fromCellValue == GameCellValue_1) {
        return 2;
    } else if (toCellValue == GameCellValue_Blank || (fromCellValue > GameCellValue_1 && fromCellValue < GAME_CELL_MAX)) {
        if (toCellValue == GameCellValue_Blank) {
            return fromCellValue - 2;
        }
        
        return fromCellValue + 1;
    }
    
    return 0;
}

- (void)cellMoveToIndex:(NSInteger)cellIndex isMoving:(BOOL)isMoving {
    NSInteger fromCellValue = _gameCells[_fromIndex];
    NSInteger nextCellValue = _gameCells[cellIndex];
    if (nextCellValue == GameCellValue_Blank && fromCellValue == GameCellValue_1) {
        _gameCells[_fromIndex] = GameCellValue_Blank;
        _gameCells[cellIndex] = GameCellValue_0;
    } else if (nextCellValue == GameCellValue_0 || fromCellValue == GameCellValue_1) {
        _gameCells[_fromIndex] = GameCellValue_Blank;
        _gameCells[cellIndex] = GameCellValue_2;
    } else if (nextCellValue == GameCellValue_Blank && fromCellValue > GameCellValue_1) {
        _gameCells[_fromIndex] = GameCellValue_Blank;
        _gameCells[cellIndex] = fromCellValue - 2;
    } else if ((nextCellValue > GameCellValue_0 && nextCellValue < GAME_CELL_MAX) &&
               (fromCellValue > GameCellValue_0 && fromCellValue < GAME_CELL_MAX) &&
               fromCellValue > nextCellValue) {
        _gameCells[_fromIndex] = GameCellValue_Blank;
        _gameCells[cellIndex] = fromCellValue + 1;
    }
    
    _moveSuccessCount += 1;
    if (!isMoving) {
        [self updateGameProgress];
    }
}

- (UIColor *)getNumberColor:(NSInteger)number {
    UIColor *color = COLOR_WITH_RGBA(0x000, 0.1);
    switch (number) {
        case GameCellValue_0:
            color = COLOR_WITH_RGB(0x27282d);
            break;
        case GameCellValue_1:
            color = COLOR_WITH_RGB(0xdea840);
            break;
        case GameCellValue_2:
            color = COLOR_WITH_RGB(0x447294);
            break;
        case GameCellValue_3:
            color = COLOR_WITH_RGB(0xff5555);
            break;
        case GameCellValue_4:
            color = COLOR_WITH_RGB(0x99889a);
            break;
        case GameCellValue_5:
            color = COLOR_WITH_RGB(0xbb3455);
            break;
        case GameCellValue_6:
            color = COLOR_WITH_RGB(0x4299dc);
            break;
        case GameCellValue_7:
            color = COLOR_WITH_RGB(0xdd9877);
            break;
        case GameCellValue_8:
            color = COLOR_WITH_RGB(0x876655);
            break;
        case GameCellValue_9:
            color = COLOR_WITH_RGB(0xcb99cc);
            break;
        case GameCellValue_10:
            color = COLOR_WITH_RGB(0x435555);
            break;
        case GameCellValue_11:
            color = COLOR_WITH_RGB(0xaacccd);
            break;
        case GameCellValue_12:
            color = COLOR_WITH_RGB(0xffdc98);
            break;
        case GameCellValue_13:
            color = COLOR_WITH_RGB(0xf54296);
            break;
        case GameCellValue_14:
            color = COLOR_WITH_RGB(0x447294);
            break;
        case GameCellValue_15:
            color = COLOR_WITH_RGB(0xbb3455);
            break;
        case GameCellValue_16:
            color = COLOR_WITH_RGB(0x000000);
            break;
        case GameCellValue_Wall:
            color = COLOR_WITH_RGB(0x666666);
            break;
        default:
            break;
    }
    
    return color;
}

- (void)updateGameProgress {
    // 判断胜利或者输的话，直接根据大于0的个数
    // 胜利的条件是，当前数组中有且仅有一个大于0的数组存在并且0的个数也为0
    // 悲剧的是，有两关本来就一个数字，但是要移动一下才能胜利，所以呢，要比较一下才行。
    if (_moveSuccessCount == 0) {
        _gameProgress = GameProgress_InPlaying;
        return;
    }
    
    NSInteger validCellCount = 0;
    NSInteger zeroCellCount = 0;
    for (NSInteger index = 0; index < GAME_CELL_MAX; index ++) {
        NSInteger nValue = _gameCells[index];
        if (nValue == GameCellValue_0) {
            zeroCellCount ++;
        } else if (nValue > GameCellValue_0 && nValue <= GameCellValue_29) {
            validCellCount ++;
        }
    }
    
    if ((zeroCellCount == 0 && validCellCount == 1) || (validCellCount == 0 && zeroCellCount == 1)) {
        _gameProgress = GameProgress_PlayerWin;
        // 如果玩家胜利了，就判断当前玩的关是否已经玩过，如果没有玩过，那么，_playerWinLevelIndex = _gameLevelIndex
        if (_playerWinLevelIndex < _gameLevelIndex) {
            _playerWinLevelIndex = _gameLevelIndex;
        }
        
    } else if (validCellCount == 0) {
        _gameProgress = GameProgress_PlayerFail;
    } else {
        _gameProgress = GameProgress_InPlaying;
    }
    
    // 告诉ui
    if ([_delegate respondsToSelector:@selector(updateGameProgress:)]) {
        [_delegate updateGameProgress:_gameProgress];
    }
}

// 保存现场
- (void)saveGameProgress {
    NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:GAME_CELL_MAX];
    for (int i = 0; i < GAME_CELL_MAX; i ++) {
        array[i] = [NSNumber numberWithInteger:_gameCells[i]];
    }
    
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults setObject:array forKey:kGameCellValue];
    [userDefaults setObject:[NSNumber numberWithInteger:_gameLevelIndex] forKey:kGameLevelIndex];
    [userDefaults setObject:[NSNumber numberWithInt:_gameProgress] forKey:kGameCellProgress];
    [userDefaults setObject:[NSNumber numberWithInteger:_playerWinLevelIndex] forKey:kPlayerWinLevelIndex];
    [userDefaults synchronize];
}

// 恢复现场
- (void)restoreGameProgress {
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    _gameLevelIndex = [[userDefaults objectForKey:kGameLevelIndex] integerValue];
    _gameProgress = [[userDefaults objectForKey:kGameCellProgress] integerValue];
    _playerWinLevelIndex = [[userDefaults objectForKey:kPlayerWinLevelIndex] integerValue];
    
#ifdef DEBUG
    _playerWinLevelIndex = 149;
#endif
    if (_gameProgress == GameProgress_InPlaying) { // 如果是在进行中，需要将数据也取出来
        NSArray *array = [userDefaults objectForKey:kGameCellValue];
        for (int i = 0; i < GAME_CELL_MAX; i ++) {
            _gameCells[i] = [[array objectAtIndex:i] integerValue];
            if (_gameCells[i] >= 0) {
                NSLog(@"i:%d--value:%ld", i, (long)_gameCells[i]);
            }
        }
        
        // 这里要发一个通知，给viewcontroller，以展示UI, 或者是在游戏进入前台的时候调用该方法，如果走到这里，要直接进入游戏界面
        [[NSNotificationCenter defaultCenter] postNotificationName:RESTORE_GAME_NOTIFICATION object:nil];
    }
}
@end
